#include "dev_key.h"

// 简单延时
void key_delay(void)
{
    uint16 t = 20000;
    while(t--);
}


// 按键初始化
void key_init(void)
{
#ifdef STM32F10X
	GPIO_InitTypeDef GPIO_InitStructure;
	KEY_RCC_APBx_CMD(KEY_RCC_APBx, ENABLE);
    
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = KEY_GPIO_Pin;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(KEY_GPIOx, &GPIO_InitStructure);
#endif
}

// 按键长按检测（此函数用于定时器中断中）
// tim_freq：定时器工作频率
// time：按键长按时间（单位：秒）
uint8 g_key_scan_flag = 1;
void key_tim_check(uint32 tim_freq, f32 time)
{
	static uint32 t = 0;
	const uint32 time_cnt = (uint32)(tim_freq * time);
	
	if (READ_KEY0 == 0 || READ_KEY1 == 0 || READ_KEY2 == 0 || READ_KEY3 == 0 
        || READ_KEY4 == 0 || READ_KEY5 == 0 || READ_KEY6 == 0 || READ_KEY7 == 0)
	{
		++t;
		if (t >= time_cnt) g_key_scan_flag = 1;
	}
	else
	{
		t = 0;
		g_key_scan_flag = 0;
	}
}

// 按键扫描
// 返回1byte数据，每个bit代表一个按键位
// time: 长按触发时间（不准确，不建议使用，即time=0时停止使用此功能）
uint8 key_scan(uint16 time)
{
    static uint16 t = 0;
    static uint8 key_scan_flag = 1;
    uint8 key_value = 0;
    
	if (time != 0)
	{
		if (t < time)   ++t;
		else            key_scan_flag = 1;
	}

    if ((key_scan_flag || g_key_scan_flag) && (READ_KEY0 == 0 || READ_KEY1 == 0 || READ_KEY2 == 0 || READ_KEY3 == 0 
        || READ_KEY4 == 0 || READ_KEY5 == 0 || READ_KEY6 == 0 || READ_KEY7 == 0))
    {
        key_delay();
        key_scan_flag = 0;
        if (READ_KEY0 == 0) key_value |= KEY0_ON;
        if (READ_KEY1 == 0) key_value |= KEY1_ON;
        if (READ_KEY2 == 0) key_value |= KEY2_ON;
        if (READ_KEY3 == 0) key_value |= KEY3_ON;
        if (READ_KEY4 == 0) key_value |= KEY4_ON;
        if (READ_KEY5 == 0) key_value |= KEY5_ON;
        if (READ_KEY6 == 0) key_value |= KEY6_ON;
        if (READ_KEY7 == 0) key_value |= KEY7_ON;
    }
    else if (READ_KEY0 && READ_KEY1 && READ_KEY2 && READ_KEY3 
        && READ_KEY4 && READ_KEY5 && READ_KEY6 && READ_KEY7)
    {
        key_scan_flag = 1;
        t = 0;
    }
    return key_value;
}

// 按键长按扫描（此函数用于定时器中断中）
// tim_freq：定时器工作频率
// time：按键长按时间（单位：秒）
// key_value：需要检测的按键
// 返回值：1，按键以达到长按时间；0，按键未达到长按时间
uint8 key_tim_scan(uint32 tim_freq, f32 time, uint8 key_value_check)
{
	static uint32 t = 0;
	static uint8 key_scan_flag = 1;
	const uint32 time_cnt = (uint32)(tim_freq * time); // 时长计数
	uint8 key_value = 0;
	
	if (key_scan_flag && (READ_KEY0 == 0 || READ_KEY1 == 0 || READ_KEY2 == 0 || READ_KEY3 == 0 
        || READ_KEY4 == 0 || READ_KEY5 == 0 || READ_KEY6 == 0 || READ_KEY7 == 0))
    {
		if (READ_KEY0 == 0) key_value |= KEY0_ON;
        if (READ_KEY1 == 0) key_value |= KEY1_ON;
        if (READ_KEY2 == 0) key_value |= KEY2_ON;
        if (READ_KEY3 == 0) key_value |= KEY3_ON;
        if (READ_KEY4 == 0) key_value |= KEY4_ON;
        if (READ_KEY5 == 0) key_value |= KEY5_ON;
        if (READ_KEY6 == 0) key_value |= KEY6_ON;
        if (READ_KEY7 == 0) key_value |= KEY7_ON;
    }
    else if (READ_KEY0 && READ_KEY1 && READ_KEY2 && READ_KEY3 
        && READ_KEY4 && READ_KEY5 && READ_KEY6 && READ_KEY7)
    {
        key_scan_flag = 1;
        t = 0;
    }
	if (key_value == key_value_check)
	{
		++t;
		if (t >= time_cnt) 
		{
			key_scan_flag = 0;
			return 1;
		}
	}
	return 0;
}
